(function(angular) {
	'use strict';
	angular.module('fs.waf').controller('cda.popup.profIntViewController', profIntViewController);
	profIntViewController.$inject = [ '$scope', '$q', '$uibModalInstance', '$timeout', '$parse', 'Constants', 'dialogsModule', 'gridService', 'modalService', 'layoutConfig' , 'authService', 'ajaxServiceFactory', 'validatorConfig', 'arithService', 'formatService'];
	function profIntViewController($scope, $q, $uibModalInstance, $timeout, $parse, Constants, dialogsModule, gridService, modalService, layoutConfig, authService, ajaxServiceFactory, validatorConfig, arithService, formatService) {
		var ctrl = this, log = $scope.loggerFactory.getLogger("profIntViewController"), ajaxService = ajaxServiceFactory.buildAjaxService({
			getProfIntOptions : {
				url : 'do/cda/dataList/profIntOptions',
				method : 'post'
			},
			getProfIntLayout : {
				url : 'do/cda/profInt/layout',
				method : 'post'
			},
			getTenerParamterLayout : {
				url : 'do/cda/tenerParamter/layout',
				method : 'post'
			}
		});
		ctrl.dialogsModule = dialogsModule;
		//ctrl.layoutConfig = layoutConfig;
		ctrl.validatorConfig = validatorConfig;
		ctrl.filterPrimaryKeys = ctrl.dialogsModule.params.filterPrimaryKeys || [];
		ctrl.prodSubtypeExtProperty = ctrl.dialogsModule.params.prodSubtypeExtProperty || {};
		ctrl.formName = "profIntForm";
		ctrl.profInt = {};
		ctrl.init = function() {
			initSubTableDefine(layoutConfig);
			ctrl.initGeneral().then(function() {
				var initProfInt = ctrl.dialogsModule.params.profInt || {};
				initProfInt.oldSpreadTierType = undefined;
				initLayoutAndDataBySpreadTierType(initProfInt).then(function(){
					if (ctrl.profIntOld) {
						ctrl.profIntOld.tierCriterias = ctrl.profIntOld.tierCriterias || [];
						ctrl.profIntOld.tierBaseRateCusts = ctrl.profIntOld.tierBaseRateCusts || [];
						ctrl.profIntOld.tierBaseRateMixs = ctrl.profIntOld.tierBaseRateMixs || [];
					}
					// for base rate customer
					initDataByProfInt();
				});
			});
		};

		ctrl.initGeneral = function() {
			var defer = $q.defer();
			// for spread tier Criteria
			initTierCriteria();
			// for base rate customer
			initCustTier();
			// for base rate mix
			initMixTier();
			getProfIntOptions().then(function(response) {
				ctrl.markupFlagOptions = response.markupFlagOptions;
				ctrl.intReviewFlagOptions = response.yesNoOptions;
				ctrl.ccyOptions = response.ccyOptions;
				ctrl.markupTypeOptions = response.markupTypeOptions;
				ctrl.allIntRateIndexOptions = response.allIntRateIndexOptions;
				ctrl.allocCodeOptions = response.allocCodeOptions;
				ctrl.intCatOptions = filterByProdSubtype("intCatOptions", response.intCatOptions);
				ctrl.intCollMethodOptions = filterByProdSubtype("intCollMethodOptions", response.intCollMethodOptions);
				ctrl.intCalcBasisOptions = filterByProdSubtype("intCalcBasisOptions", response.intCalcBasisOptions);
				ctrl.intRefundTypeOptions = filterByProdSubtype("intRefundTypeOptions", response.intRefundTypeOptions);
				ctrl.allIntRateTypeOptions = filterByProdSubtype("intRateTypeOptions", response.intRateTypeOptions);
				ctrl.pctCalcBaseOptions = response.pctCalcBaseOptions;
				ctrl.allIntBaseTypeOptions = filterByProdSubtype("intBaseTypeOptions", response.intBaseTypeOptions);
				ctrl.intBaseDateTypeOptions = response.intBaseDateTypeOptions;
				ctrl.intSpreadTypeOptions = response.intSpreadTypeOptions;
				ctrl.spreadTierTypeOptions = filterByProdSubtype("spreadTierTypeOptions", response.spreadTierTypeOptions);
				ctrl.spreadTierType2Options = filterByProdSubtype("spreadTierTypeOptions", response.spreadTierTypeOptions);
				ctrl.copySpreadTierTypeOptions = angular.copy(ctrl.spreadTierTypeOptions);
				ctrl.copySpreadTierType2Options = angular.copy(ctrl.spreadTierType2Options);
				ctrl.tierCalcTypeOptions = response.tierCalcTypeOptions;
				ctrl.intInsTypeOptions = response.intInsTypeOptions;
				ctrl.allIntBaseCustomAlgs = response.intBaseCustomAlgs;
				defer.resolve();
			}, angular.noop);
			return defer.promise;
		};
		function getProfIntOptions() {
			var defer = $q.defer();
			ajaxService.getProfIntOptions({}).then(function(response) {
				var profIntOptions = {};
				if (response.data) {
					angular.forEach(response.data, function(value, key) {
						var tempValue = {};
						tempValue = value;
						profIntOptions[key] = tempValue;
					});
				}
				defer.resolve(profIntOptions);
			});
			return defer.promise;
		}
		
		function initDataByProfInt() {
			if (ctrl.profInt.tierBaseRateCusts) {
				var preCustTierTenor;
				for (var i = 0; i < ctrl.profInt.tierBaseRateCusts.length; i++) {
					var tierBaseRateCust = ctrl.profInt.tierBaseRateCusts[i];
					ctrl.intBaseCustomAlgChanged(tierBaseRateCust);
					if (i == 0) {
						tierBaseRateCust.tenerFrom = 0;
						preCustTierTenor = tierBaseRateCust.tener;
						continue;
					} else {
//						tierBaseRateCust.tenerFrom = arithService.add(preCustTierTenor, 1);
						tierBaseRateCust.tenerFrom = preCustTierTenor;
						preCustTierTenor = tierBaseRateCust.tener;
					}
				}
			}
		}
		
		function filterByProdSubtype(type, options) {
			if (!options || options.length == 0) return options;
			var filter;
			if (type == 'intCatOptions') {
				filter = ctrl.prodSubtypeExtProperty.upIntCats;
				if (!filter) {
					return null;
				} else if (filter == '*') {
					return options;
				}
			} else if (type == 'intCollMethodOptions') {
				filter = ctrl.prodSubtypeExtProperty.upIntCollMethods;
				if (!filter) {
					return options;
				}
			} else if (type == 'intCalcBasisOptions') {
				filter = ctrl.prodSubtypeExtProperty.upIntCalcBases;
				if (!filter) {
					return options;
				}
			} else if (type == 'intRefundTypeOptions') {
				filter = ctrl.prodSubtypeExtProperty.upIntRefundTypes;
				if (!filter) {
					return options;
				}
			} else if (type == 'intRateTypeOptions') {
				filter = ctrl.prodSubtypeExtProperty.upIntRateTypes;
				if (!filter) {
					return options;
				}
			} else if (type == 'intBaseTypeOptions') {
				filter = ctrl.prodSubtypeExtProperty.upIntBaseTypes;
				if (!filter) {
					return options;
				}
			} else if (type == 'spreadTierTypeOptions') {
				filter = ctrl.prodSubtypeExtProperty.upIntTierTypes;
				if (!filter) {
					return options;
				} else {
					filter = filter + "N";// add 'NO TIER' for select 
				}
			}
			
			var filterOptions = [];
			for (var i = 0; i < options.length; i++) {
				var loadVal = options[i].value;
				if (filter.indexOf(loadVal) >= 0) {
					filterOptions[filterOptions.length] = options[i];
				}
			}
			return filterOptions;
		}
		
		function initLayoutAndDataBySpreadTierType(initProfInt) {
			var defer = $q.defer();
			if(initProfInt.spreadTierType && initProfInt.spreadTierType != 'N' && initProfInt.spreadTierType != initProfInt.oldSpreadTierType){
				initProfInt.oldSpreadTierType = initProfInt.spreadTierType;
				var params = {
					"action" : "profIntView",
					"parmSubcat" : initProfInt.spreadTierType
				};
				ajaxService.getProfIntLayout(params).then(function(response) {
					var tmp = angular.copy(initProfInt);
					// 1. change layout
					$timeout(function(){
						ctrl.layoutConfig = response.data;
					});
					// reset model after change layout
					$timeout(function(){
						ctrl.profInt = tmp;
						// format by new spreadTierType
						if (ctrl.profInt.spreadTierType && ctrl.profInt.spreadTierType != 'N') {
							formatCriteria(ctrl);
						}
						changeColumnDefsForTierType();
						defer.resolve();
					});
				});
			} else {
				ctrl.layoutConfig = layoutConfig;
				ctrl.profInt = initProfInt;
				// format by new spreadTierType
				if (ctrl.profInt.spreadTierType && ctrl.profInt.spreadTierType != 'N') {
					formatCriteria(ctrl);
				}
				changeColumnDefsForTierType();
				defer.resolve();
			}
			return defer.promise;
		}
		
		function changeLayoutBySpreadTierType() {
			if(ctrl.profInt.spreadTierType && ctrl.profInt.spreadTierType != ctrl.profInt.oldSpreadTierType){
				ctrl.profInt.oldSpreadTierType = ctrl.profInt.spreadTierType;
				var params = {
					"action" : "profIntView",
					"parmSubcat" : ctrl.profInt.spreadTierType
				};
				ajaxService.getProfIntLayout(params).then(function(response) {
					var tmp = angular.copy(ctrl.profInt);
					// 1. change layout
					$timeout(function(){
						ctrl.layoutConfig = response.data;
					});
					// reset model after change layout
					$timeout(function(){
						// format by new spreadTierType
						if (ctrl.profInt.spreadTierType && ctrl.profInt.spreadTierType != 'N') {
							formatCriteria(ctrl);
						}
						changeColumnDefsForTierType();
						ctrl.profInt = tmp;
					});
				});
			}
			
		}
		
		ctrl.ccyChanged = function(value) {
			if (ctrl.profInt.ccy) {
				// filter intRateIndex by ccy
				var intRateIndexOptions = [];
				for (var i = 0; i < ctrl.allIntRateIndexOptions.length; i++) {
					var _intIndex = ctrl.allIntRateIndexOptions[i];
					if (_intIndex.extProperty.ccy == ctrl.profInt.ccy) {
						intRateIndexOptions.push(ctrl.allIntRateIndexOptions[i]);
					}
				}
				ctrl.intRateIndexOptions = intRateIndexOptions;
				ctrl.copyIntRateIndexOptions = angular.copy(ctrl.intRateIndexOptions);
				// same as intRateIndex
				ctrl.lpRateIndexOptions = angular.copy(intRateIndexOptions);
				
				resetIntRateIndexByIntBaseType(ctrl);
				
				formatCriteria(ctrl);
				formatCriteria2(ctrl);
			}
		};
		
		ctrl.intCatChanged = function(value) {
		};
		
		ctrl.intReviewFlagChanged = function(value) {
			filterSpreadTierTypeOptions(ctrl);
		};
		ctrl.intSpreadTypeChanged = function(value) {
			filterSpreadTierTypeOptions(ctrl);
		};
		
		ctrl.intRateSpreadAmtChanged = function(obj) {
			// if intRateType == 'A', intRateSpreadAmt and spreadTierType must one exist
			if (obj.intRateSpreadAmt && obj.intRateSpreadAmt != 0 && ctrl.profInt.intRateType == 'A') {
				ctrl.profInt.spreadTierType = 'N';
			};
		};
		
		ctrl.intRateSpreadPrecChanged = function(obj) {
			// if intRateType == 'P', intRateSpreadPrec and spreadTierType must one exist
			if (obj.intRateSpreadPrec && obj.intRateSpreadPrec != 0 && ctrl.profInt.intRateType == 'P') {
				ctrl.profInt.spreadTierType = 'N';
			};
		};
		
		ctrl.intCollMethodChanged = function(value) {
			if (ctrl.profInt.intCollMethod) {
				// filter intRateIndex by ccy
				var intRateTypeOptions = [];
				for (var i = 0; i < ctrl.allIntRateTypeOptions.length; i++) {
					var _intType = ctrl.allIntRateTypeOptions[i];
					// Arrears (pay later)
					if (ctrl.profInt.intCollMethod == 'A') {
						if (_intType.value == 'F' || _intType.value == 'V'|| _intType.value == 'Y') {
							intRateTypeOptions.push(ctrl.allIntRateTypeOptions[i]);
						}
					} 
					// Prepaid (Discounting)	
					else if (ctrl.profInt.intCollMethod == 'P') {
						if (_intType.value == 'F' || _intType.value == 'P' || 
							_intType.value == 'A' || _intType.value == 'Y' || 
							_intType.value == 'N' || _intType.value == 'S') {
							intRateTypeOptions.push(ctrl.allIntRateTypeOptions[i]);
						}
					}
				}
				ctrl.intRateTypeOptions = intRateTypeOptions;
			}
		};
		
		ctrl.intRateTypeChanged = function(value) {
			if (ctrl.profInt.intRateType) {
				if("V" != ctrl.profInt.intRateType) {
					ctrl.profInt.intSpreadType = "F";
				}
				// filter intRateIndex by ccy
				var intBaseTypeOptions = [];
				for (var i = 0; i < ctrl.allIntBaseTypeOptions.length; i++) {
					var _intBaseType = ctrl.allIntBaseTypeOptions[i];
					
					if (ctrl.profInt.intRateType == 'V') {
						// if intRateType 'Variable', intBaseType 'Custom' and 'Interpolation' cannot be selected 
						if (!(_intBaseType.value == 'C' || _intBaseType.value == 'I')) {
							intBaseTypeOptions.push(ctrl.allIntBaseTypeOptions[i]);
						}
					} else {
						//only the Rate Type=FIX the option 'CUSTOM' in Base Rate Type can be show。
						if (ctrl.profInt.intRateType != 'F') {
							if (_intBaseType.value != 'C') {
								intBaseTypeOptions.push(ctrl.allIntBaseTypeOptions[i]);
							}
						} else {
							intBaseTypeOptions.push(ctrl.allIntBaseTypeOptions[i]);
						}
					}
				}
				ctrl.intBaseTypeOptions = intBaseTypeOptions;
				//
				if (ctrl.profInt.intRateType != 'V') {
					ctrl.profInt.intSpreadType = ctrl.profInt.intSpreadType || 'F';
				}
				//default value
				//Rate Type=FIXED PERCENTAGE，
				if(ctrl.profInt.intRateType == 'P') {
					ctrl.profInt.pctCalcBase = ctrl.profInt.pctCalcBase || 'A';
				}
				
				changeColumnDefsForTierType();
			}
		};
		
		ctrl.intBaseTypeChanged = function(value) {
			if (ctrl.profInt.intBaseType) {
				resetIntBaseCustomAlgsByIntBaseType(ctrl);
				resetIntRateIndexByIntBaseType(ctrl);
			}
			// need clear
			if (ctrl.profInt.markupFlag == 'Y' || ctrl.profInt.markupFlag == 'F' || ctrl.profInt.intBaseType != 'C') {
				ctrl.profInt.tierBaseRateCusts = [];
			}
			// need clear
			if (ctrl.profInt.markupFlag == 'Y' ||ctrl.profInt.markupFlag == 'F' || ctrl.profInt.intBaseType != 'M') {
				ctrl.profInt.tierBaseRateMixs = [];
			}
		};
		
		function resetIntBaseCustomAlgsByIntBaseType(ctrl) {
			var intBaseCustomAlgData = [];
			for (var i = 0; i < ctrl.allIntBaseCustomAlgs.length; i++) {
				var _intBaseCustomAlg = ctrl.allIntBaseCustomAlgs[i];
				var _filterTypes = _intBaseCustomAlg.extProperty.INT_BASE_TYPES;
				if (_filterTypes && _filterTypes.indexOf(ctrl.profInt.intBaseType) >= 0) {
					intBaseCustomAlgData.push(_intBaseCustomAlg);
				}
			}
			ctrl.intBaseCustomAlgs = intBaseCustomAlgData;
		}
		function resetIntRateIndexByIntBaseType(ctrl) {
			var resultData = [];
			if(ctrl.copyIntRateIndexOptions) {
				var rateIndexValueStr = "";
				if (ctrl.profInt.intBaseType == "F") {
					for (var i = 0; i < ctrl.copyIntRateIndexOptions.length; i++) {
						var intRateIndex = ctrl.copyIntRateIndexOptions[i];
						var intIndexObj = intRateIndex.extProperty;
						var intIndexCode = intIndexObj.intIndexCode;
						var dataObj = {};
						dataObj.value = intIndexCode;
						//remove the sitecode, like 'MDBANK:'
						dataObj.label = intIndexCode.substring(intIndexObj.siteCode.length + intIndexObj.ccy.length + 2, intIndexCode.length);
						resultData.push(dataObj);
					}
				} else if (ctrl.profInt.intBaseType == "N" || ctrl.profInt.intBaseType == "C" || ctrl.profInt.intBaseType == "I") {
					for (var i = 0; i < ctrl.copyIntRateIndexOptions.length; i++) {
						var intRateIndex = ctrl.copyIntRateIndexOptions[i];
						var intIndexObj = intRateIndex.extProperty;
						var tenorFlag = intIndexObj.tenorFlag;
						var dataObj = {};
						dataObj.value = intIndexObj.siteCode + ":" + intIndexObj.ccy + ":" + intIndexObj.intIndexName;
						dataObj.label = intIndexObj.intIndexName;
						if(tenorFlag == "Y" && rateIndexValueStr.indexOf(dataObj.value + ",") == -1) {
							rateIndexValueStr += dataObj.value + ",";
							resultData.push(dataObj);
						}
					}
				} else {
					for (var i = 0; i < ctrl.copyIntRateIndexOptions.length; i++) {
						var intRateIndex = ctrl.copyIntRateIndexOptions[i];
						var intIndexObj = intRateIndex.extProperty;
						var intIndexCode = intIndexObj.intIndexCode;
						var dataObj = {};
						dataObj.value = intIndexCode;
						//remove the sitecode, like 'MDBANK:'
						dataObj.label = intIndexCode.substring(intIndexObj.siteCode.length + intIndexObj.ccy.length + 2, intIndexCode.length);
						resultData.push(dataObj);
					}
				}
			}
			ctrl.intRateIndexOptions = resultData;
		}
		
		ctrl.intBaseCustomAlgChanged = function(rowObj){
			if(rowObj.alg){
				ajaxService.getTenerParamterLayout({
					"parmSubcat" : rowObj.alg //INTERPOLATION_GIVEN
				}).then(function(response) {
					if(response.data){
						var config = response.data.formConfigs.custTier.gridConfigs.TENORS;
						config.gridClass = "col-sm-12";
						config.inputClass = "input-sm";
						rowObj.TENORS = config;
						if(!rowObj.dynamicParams){
							rowObj.dynamicParams = {
								TENORS : {}
							};
						}
						angular.merge(rowObj.dynamicParams.TENORS, config.dynamicParameter);
					}else{
						rowObj.TENORS = {
							"type" : "label"
						};
						if(rowObj.dynamicParams && rowObj.dynamicParams.TENORS){
							rowObj.dynamicParams.TENORS.value = "";
						}
					}
				});
			}else{
				rowObj.TENORS = {
					"type" : "label"
				};
				if(rowObj.dynamicParams && rowObj.dynamicParams.TENORS){
					rowObj.dynamicParams.TENORS.value = "";
				}
			}
		};
		
		ctrl.intRefundTypeChanged = function(value) {
			if (ctrl.profInt.intRefundType && !(ctrl.profInt.intRefundType == 'A' || ctrl.profInt.intRefundType == 'B')) {
				// readonly and also need clear data
				ctrl.profInt.intRefundDay = '';
			}
		};
		
		ctrl.markupFlagChanged = function(value) {
			if (ctrl.profInt.markupFlag == 'N') {
				// give default value
				ctrl.profInt.intCollMethod = ctrl.profInt.intCollMethod || 'A';
				ctrl.profInt.intRefundType = ctrl.profInt.intRefundType || 'N';
				ctrl.profInt.intCalcBasis = ctrl.profInt.intCalcBasis || '366/366';
				ctrl.profInt.intRateType = ctrl.profInt.intRateType || 'F';
				ctrl.profInt.intBaseType = ctrl.profInt.intBaseType || 'N';
				ctrl.profInt.intSpreadType = ctrl.profInt.intSpreadType || 'F';
				ctrl.profInt.intRateSpread = ctrl.profInt.intRateSpread || 0;
				ctrl.profInt.intRateTax = ctrl.profInt.intRateTax || 0;
				ctrl.profInt.intRateCof = ctrl.profInt.intRateCof || 0;
				ctrl.profInt.intRateIns = ctrl.profInt.intRateIns || 0;
				ctrl.profInt.intInsType = ctrl.profInt.intInsType || "A";
				ctrl.profInt.spreadTierType = ctrl.profInt.spreadTierType || 'N';
			}  else if (ctrl.profInt.markupFlag == 'F' || ctrl.profInt.markupFlag == 'Y') {
				// need clear
				delete ctrl.profInt.intCollMethod;
				delete ctrl.profInt.intRateType;
				delete ctrl.profInt.intBaseType;
				delete ctrl.profInt.intSpreadType;
				ctrl.profInt.tierCriterias = [];
				ctrl.profInt.tierBaseRateCusts = [];
				ctrl.profInt.tierBaseRateMixs = [];
			}
		};
		
		function filterSpreadTierTypeOptions(ctrl) {
			if (!ctrl.profInt) return;
			if (ctrl.profInt.intReviewFlag && ctrl.profInt.intReviewFlag == 'Y') {
				//remove the tiertype
				var resultOptions = [];
				//Interest Review Flag=Yes，Spread Tier Type is only support Number of days option
				angular.forEach(ctrl.copySpreadTierTypeOptions, function(obj) {
					if (obj.value == 'S') {
						resultOptions.push(obj);
					}
				});
				ctrl.spreadTierTypeOptions = resultOptions;
				// if intReviewFlag == 'Y', spreadTierType must 'S'
				ctrl.profInt.spreadTierType = 'S';
			} else if(ctrl.profInt.intSpreadType == 'V') {//if intSpreadType = Variable, the spreadTierType must not be N.
				var resultOptions = [];
				angular.forEach(ctrl.copySpreadTierTypeOptions, function(obj) {
					if (!(obj.value == "N" || obj.value == ctrl.profInt.spreadTierType2)) {
						resultOptions.push(obj);
					}
				});
				ctrl.spreadTierTypeOptions = resultOptions;
			} else {
				var resultOptions = [];
				angular.forEach(ctrl.copySpreadTierTypeOptions, function(obj) {
					if (obj.value != ctrl.profInt.spreadTierType2 || obj.value == 'N') {
						resultOptions.push(obj);
					}
				});
				ctrl.spreadTierTypeOptions = resultOptions;
			}
		}
		
		function filterSpreadTierType2Options(ctrl) {
			if (!ctrl.profInt) return;
			// spreadTierType2 remove the tiertype which is used in spreadTierType
			var resultOptions = [];
			angular.forEach(ctrl.copySpreadTierType2Options, function(obj) {
				if (obj.value != ctrl.profInt.spreadTierType) {
					resultOptions.push(obj);
				}
			});
			ctrl.spreadTierType2Options = resultOptions;
		}
		
		// this must be out of ajax
		function initSubTableDefine(layoutConfig) {
			//init tierCriterias
			if(ctrl.validatorConfig) layoutConfig.formConfigs.tierCriteria.tableConfigs.table.validatorConfig = ctrl.validatorConfig.profInts ? ctrl.validatorConfig.profInts.tierCriterias : {};
			ctrl.tierCriteriaInnerGridOptions = gridService.createInnerGridOptions($scope, layoutConfig.formConfigs.tierCriteria.tableConfigs.table, tierCriteriaRowSelectionChanged);
			ctrl.tierCriteriaInnerGridOptions.data = 'vm.profInt.tierCriterias';
			ctrl.tierCriteriaInnerGridOptions.verifyData = 'vm.profIntOld.tierCriterias';
			function tierCriteriaRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedTierCriterias = selectedRows;
			}
			//init tierBaseRateCusts
			if(ctrl.validatorConfig) layoutConfig.formConfigs.custTier.tableConfigs.table.validatorConfig = ctrl.validatorConfig.profInts ? ctrl.validatorConfig.profInts.tierBaseRateCusts : {};
			ctrl.custTierInnerGridOptions = gridService.createInnerGridOptions($scope, layoutConfig.formConfigs.custTier.tableConfigs.table, custTierRowSelectionChanged);
			ctrl.custTierInnerGridOptions.data = 'vm.profInt.tierBaseRateCusts';
			ctrl.custTierInnerGridOptions.verifyData = 'vm.profIntOld.tierBaseRateCusts';
			function custTierRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedCustTiers = selectedRows;
			}
			//init tierBaseRateMixs
			if(ctrl.validatorConfig) layoutConfig.formConfigs.mixTier.tableConfigs.table.validatorConfig = ctrl.validatorConfig.profInts ? ctrl.validatorConfig.profInts.tierBaseRateMixs : {};
			ctrl.mixTierInnerGridOptions = gridService.createInnerGridOptions($scope, layoutConfig.formConfigs.mixTier.tableConfigs.table, mixTierRowSelectionChanged);
			ctrl.mixTierInnerGridOptions.data = 'vm.profInt.tierBaseRateMixs';
			ctrl.mixTierInnerGridOptions.verifyData = 'vm.profIntOld.tierBaseRateMixs';
			function mixTierRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedMixTiers = selectedRows;
			}
		};
		
		/*******************Spread Tier**********************/
		function initTierCriteria() {
			ctrl.spreadTierTypeChanged = function(value) {
				if (ctrl.profInt.spreadTierType && ctrl.profInt.spreadTierType != 'N') {
					// readonly and also need clear data
					ctrl.profInt.intRateSpread = 0;
					ctrl.profInt.intRateSpreadAmt = 0;
					ctrl.profInt.intRateSpreadPrec = 0;
					
					// spreadTierType2 remove the tiertype which is used in spreadTierType
					filterSpreadTierType2Options(ctrl);
				}
				// need clear
				if (ctrl.profInt.markupFlag == 'Y' || ctrl.profInt.markupFlag == 'F' || ctrl.profInt.spreadTierType == 'N') {
					ctrl.profInt.tierCriterias = [];
				}
				
				changeLayoutBySpreadTierType();
			};
			
			ctrl.spreadTierType2Changed = function(value) {
				if (ctrl.profInt.spreadTierType2 && ctrl.profInt.spreadTierType2 != 'N') {
					filterSpreadTierTypeOptions(ctrl);
				}
				
				changeColumnDefsForTierType();
				
				var spreadTierType2 = ctrl.profInt.spreadTierType2;
				if (spreadTierType2 && spreadTierType2 != 'N') {
					// format by new spreadTierType2
					formatCriteria2(ctrl);
					// need hidden some first column criteria
					resetHasFrontSameCriteria(ctrl);
				} else if (spreadTierType2 == 'N') {
					// also need open hidden first column
					resetHasFrontSameCriteria(ctrl);
					// also format first column criteria, some hidden value may be error show format
					// format by new spreadTierType
					formatCriteria(ctrl);
				}
			};

			ctrl.criteriaChanged = function(currTierCriteria) {
				var tierByVal = ctrl.profInt.spreadTierType;
				var ccy = ctrl.profInt.ccy;
				// format
				var criteria = formatTierCriteria(currTierCriteria.criteria, tierByVal, ccy);
				currTierCriteria.criteria = criteria;
				// if master, then need reset sub line
				var _selectedTierCriteriaIndex;
				angular.forEach(ctrl.profInt.tierCriterias, function(tierCriteria, index) {
					if (tierCriteria.$$hashKey == currTierCriteria.$$hashKey) {
						_selectedTierCriteriaIndex = index;
					}
				});
				if ((_selectedTierCriteriaIndex || _selectedTierCriteriaIndex == 0) && _selectedTierCriteriaIndex < ctrl.profInt.tierCriterias.length - 1) {
					for (var i = _selectedTierCriteriaIndex + 1; i < ctrl.profInt.tierCriterias.length; i++) {
						var tierCriteria = ctrl.profInt.tierCriterias[i];
						// belong to master
						if (tierCriteria.hasFrontSameCriteria == 'Y') {
							tierCriteria.criteria = criteria;
						} else {
							break;
						}
					}
				}
			};
			
			ctrl.criteria2Changed = function(currTierCriteria) {
				var tierByVal = ctrl.profInt.spreadTierType2;
				var ccy = ctrl.profInt.ccy;
				// format
				var criteria2 = formatTierCriteria(currTierCriteria.criteria2, tierByVal, ccy);
				currTierCriteria.criteria2 = criteria2;
			};
		}
		
		function changeColumnDefsForTierType() {
			var viewFlag = true;
			// Amount:A U
		    // other is number
			var dynamicType, dynamicFormat;
			if (ctrl.profInt.spreadTierType == 'A' || ctrl.profInt.spreadTierType == 'U') {
				dynamicType = "money";
				dynamicFormat = "vm.profInt.ccy";
			} else {
				// default
				dynamicType = "number";
				dynamicFormat = "integer";
			}
			var dynamicType2, dynamicFormat2;
			if (ctrl.profInt.spreadTierType2 == 'A' || ctrl.profInt.spreadTierType2 == 'U') {
				dynamicType2 = "money";
				dynamicFormat2 = "vm.profInt.ccy";
			} else {
				// default
				dynamicType2 = "number";
				dynamicFormat2 = "integer";
			}
			// rate:F V Y N S
			// Percentage:P
			// Amount:A
			var criteriaValueType, criteriaValueFormat;
			if (ctrl.profInt.intRateType == 'F' || ctrl.profInt.intRateType == 'V' || ctrl.profInt.intRateType == 'Y' || 
					ctrl.profInt.intRateType == 'N' || ctrl.profInt.intRateType == 'S') {
				criteriaValueType = "percentage";
				criteriaValueFormat = "interestRate";
			} else if (ctrl.profInt.intRateType == 'P') {
				criteriaValueType = "percentage";
				criteriaValueFormat = "nfmtMoney2";
			} else if (ctrl.profInt.intRateType == 'A') {
				criteriaValueType = "money";
				criteriaValueFormat = "vm.profInt.ccy";
			} else {
				// default
				criteriaValueType = "percentage";
				criteriaValueFormat = "interestRate";
			}
			var columnDefs = [
                {
		            "label": "label.feecode.criteria",
		            "model": "criteria",
                    "type": dynamicType,
                    "format": dynamicFormat,
                    "readonly": viewFlag,
                    "options": {
            			"data": "vm.criteriaOptions",
            			"callback": {
            				"changed": "vm.criteriaChanged"
            			}
            		},
		            "show": "row.entity.hasFrontSameCriteria == 'N'"
		        },
                {
                    "label": "label.feecode.criteriavalue",
                    "model": "criteriaValue",
                    "type": criteriaValueType,
                    "format": criteriaValueFormat,
                    "readonly": viewFlag,
                    "options": {}
                }
            ];
			var columnDefs2 = [
                {
		            "label": "label.feecode.criteria",
		            "model": "criteria",
                    "type": dynamicType,
                    "format": dynamicFormat,
                    "readonly": viewFlag,
                    "options": {
            			"data": "vm.criteriaOptions",
            			"callback": {
            				"changed": "vm.criteriaChanged"
            			}
            		},
		            "show": "row.entity.hasFrontSameCriteria == 'N'"
		        },{
		            "label": "label.feecode.criteria2",
		            "model": "criteria2",
                    "type": dynamicType2,
                    "format": dynamicFormat2,
                    "readonly": viewFlag,
                    "options": {
            			"data": "vm.criteria2Options",
            			"callback": {
            				"changed": "vm.criteria2Changed"
            			}
            		}
		        },
                {
                    "label": "label.feecode.criteriavalue",
                    "model": "criteriaValue",
                    "type": criteriaValueType,
                    "format": criteriaValueFormat,
                    "readonly": viewFlag,
                    "options": {}
                }
            ];
			if (ctrl.profInt.spreadTierType2 && ctrl.profInt.spreadTierType2 != 'N') {
				columnDefs = columnDefs2;
			}
			if(ctrl.validatorConfig) ctrl.layoutConfig.formConfigs.tierCriteria.tableConfigs.table.validatorConfig = ctrl.validatorConfig.profInts ? ctrl.validatorConfig.profInts.tierCriterias : {};
			ctrl.layoutConfig.formConfigs.tierCriteria.tableConfigs.table.columnDefs = columnDefs;
			ctrl.tierCriteriaInnerGridOptions = gridService.createInnerGridOptions($scope, ctrl.layoutConfig.formConfigs.tierCriteria.tableConfigs.table, tierCriteriaRowSelectionChanged);
			ctrl.tierCriteriaInnerGridOptions.data = 'vm.profInt.tierCriterias';
			ctrl.tierCriteriaInnerGridOptions.verifyData  = 'vm.profIntOld.tierCriterias';
			ctrl.tierCriteriaInnerGridOptions.filterRowOperation = function (row, operation) {
				if (row.entity.hasFrontSameCriteria == 'N') {
					return false;
				} else {
					return true;
				}
			};
			function tierCriteriaRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedTierCriterias = selectedRows;
			}
		}
		
		function formatCriteria(ctrl) {
			if (ctrl.profInt.spreadTierType == 'A' || ctrl.profInt.spreadTierType == 'U') {
				var tierByVal = ctrl.profInt.spreadTierType;
				var ccy = ctrl.profInt.ccy;
				if (ctrl.profInt.tierCriterias && ctrl.profInt.tierCriterias.length > 0) {
					for (var i = 0; i < ctrl.profInt.tierCriterias.length; i++) {
						var tierCriteria = ctrl.profInt.tierCriterias[i];
						var criteria = formatTierCriteria(tierCriteria.criteria, tierByVal, ccy);
						tierCriteria.criteria = criteria;
					}
				}
			}
		}
		
		function formatCriteria2(ctrl) {
			if (ctrl.profInt.spreadTierType2 == 'A' || ctrl.profInt.spreadTierType2 == 'U') {
				var tierByVal = ctrl.profInt.spreadTierType2;
				var ccy = ctrl.profInt.ccy;
				if (ctrl.profInt.tierCriterias && ctrl.profInt.tierCriterias.length > 0) {
					for (var i = 0; i < ctrl.profInt.tierCriterias.length; i++) {
						var tierCriteria = ctrl.profInt.tierCriterias[i];
						var criteria2 = formatTierCriteria(tierCriteria.criteria2, tierByVal, ccy);
						tierCriteria.criteria2 = criteria2;
					}
				}
			}
		}
		
		/**
		 * format the assinged line's criteria in tier table
		 */
		function formatTierCriteria(criteria, tierByVal, ccy){
			if(criteria && isNaN(criteria)) criteria = '';
			if (!criteria || arithService.eq(criteria, 0)) return;
			var value = criteria;
			if(tierByVal == "T"){
				//LOAN TENOR need format 1,231,231
//				value = formatService.formatNumber(formatService.parseNumber(criteria), "nfmtMoney0");
				return value;
			} else if(tierByVal == "U" || tierByVal == "A" ){
				//LOAN AMOUNT need format 1,231,231.00
//				value = formatService.formatMoney(formatService.parseMoney(criteria), ccy);
				return value;
			} else {
				if(arithService.eq(criteria, 0) && criteria.length > 1) {//00...
					value = criteria = '';
				}
				if(tierByVal == "E"){//DATE
//					var dateVal = criteria;
//					if(arithService.gt(dateVal, 0) && !isDate(String(dateVal))){
//						value = '';
//					}
				} else if(tierByVal == "R"){//YEAR
					if(arithService.gt(criteria, 9999)){
						value = '';
					}
				} else if(tierByVal == "Y"){//DAY
					if(arithService.gt(criteria, 31)){
						value = '';
					}
				} else if(tierByVal == "H"){//MONTH
					if(arithService.gt(criteria, 12)){
						value = '';
					}
				} else if(tierByVal == "K"){//WEEK
					if(arithService.gt(criteria, 7)){
						value = '';
					}
				}
				//roundNum(tierCriteria.criteria, 0)
//				value = formatService.round(value, 0);
				return value;
			}
		}
		
		/**
		 * if the date is valid: 20090102, 2009-01-02, 2009/01/02
		 */
		function isDate(s){
			var r = s.match(/^(\d{1,4})(|-|\/)(\d{1,2})\2(\d{1,2})$/); 
			if(r==null)return false; 
			var d= new Date(r[1], r[3]-1, r[4]); 
			return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]);
		}
		
		/**
		 * reset TierCriteria for hasSameCriteria
		 * if spreadTierType2 isnot "N", then may be hidden hasSameCriteria
		 * if spreadTierType2 is "N", then open all hidden first columns
		 */
		function resetHasFrontSameCriteria (ctrl) {
			// need hidden some first column criteria
			if (ctrl.profInt.spreadTierType != "N" && ctrl.profInt.spreadTierType2 != "N") {
				if (ctrl.profInt.tierCriterias && ctrl.profInt.tierCriterias.length > 0) {
					var lastCriteria;
					for (var i = 0; i < ctrl.profInt.tierCriterias.length; i++) {
						var tierCriteria = ctrl.profInt.tierCriterias[i];
						var criteria = tierCriteria.criteria;
						if (ctrl.profInt.spreadTierType == "T"){
							criteria = formatService.parseNumber(criteria);
						} else if(ctrl.profInt.spreadTierType == "U" || ctrl.profInt.spreadTierType == "A" ){
							criteria = formatService.parseMoney(criteria);
						} 
						if (i == 0) {
							lastCriteria = criteria;
							tierCriteria.hasFrontSameCriteria = "N";
							continue;
						}
						//
						if (lastCriteria && arithService.eq(criteria, lastCriteria)) {
							tierCriteria.hasFrontSameCriteria = "Y";
						} else {
							tierCriteria.hasFrontSameCriteria = "N";
						}
						lastCriteria = criteria;
					}
				}
			} 
			// also need open hidden first column
			else if (ctrl.profInt.spreadTierType != "N" && ctrl.profInt.spreadTierType2 == "N") {
				if (ctrl.profInt.tierCriterias && ctrl.profInt.tierCriterias.length > 0) {
					for (var i = 0; i < ctrl.profInt.tierCriterias.length; i++) {
						var tierCriteria = ctrl.profInt.tierCriterias[i];
						tierCriteria.hasFrontSameCriteria = "N";
					}
				}
			}
		}
		/*******************Spread Tier**********************/
		
		/*******************Customer Tier**********************/
		function initCustTier() {
			ctrl.custTierMoreDataDyna = function (obj){
				var params = {};
				// for get dynaparm page
				params.parmSubcat = obj.alg;
				// for data on edit page popup
				params.custDynaparm = {};
				params.custDynaparm.dynamicParams = obj.dynamicParams;
				modalService.openCustomDialogs({
				   'title': 'Cust More Data',
				   'dialogsModule' : 'cda.custdynaparm.popupview',
				   'params': params,
				   'btnCallback' : {
						'ok' : function(resultList) {
						}
					}	
				});
			};
			
			ctrl.tenorChanged = function () {
				caculateTenorFrom();
			}
			function caculateTenorFrom() {
				var rowDatas = ctrl.profInt.tierBaseRateCusts;
				if(rowDatas && rowDatas.length > 0) {
					for(var i = 0; i < rowDatas.length; i++) {
						var preIndex = i - 1;
						if(preIndex >= 0) {
							rowDatas[i].tenerFrom = rowDatas[preIndex].tener;
						} else {
							rowDatas[i].tenerFrom = 0;
						}
					}
				}
			}
		}
		/*******************Customer Tier**********************/
		
		/*******************Mix Tier**********************/
		function initMixTier() {
		}
		/*******************Mix Tier**********************/
		
		
		ctrl.close = function() {
			if (!dialogsModule.btnCallback || !dialogsModule.btnCallback['close'] || dialogsModule.btnCallback['close']() !== false) {
				$uibModalInstance.dismiss();
			}
		};
		
	}
})(angular);
